using B.S.XZYData.Api.Wrter.Application.Command.Process;
using B.S.XZYData.Domain.ZSHH;
using B.S.XZYData.Domain.RBAC;
using B.S.XZYData.Domain.ZSH;
using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure.Interface;
using MediatR;
using System.Transactions;
using Yitter.IdGenerator;
using System.Linq;

namespace B.S.XZYData.Api.Wrter.Application.Handler.Process
{
    /// <summary>
    /// 导入工序处理器
    /// </summary>
    public class ImportProcessHandler : IRequestHandler<ImportProcessCommand, ApiResult<int>>
    {
        private readonly IBaseRepository<Domain.ZSHH.Process> processRepo;
        private readonly IBaseRepository<RoleModel> roleRepo;
        private readonly IBaseRepository<Defective> defectiveRepo;
        private readonly ILogger<ImportProcessHandler> logger;

        public ImportProcessHandler(
            IBaseRepository<Domain.ZSHH.Process> processRepo,
            IBaseRepository<RoleModel> roleRepo,
            IBaseRepository<Defective> defectiveRepo,
            ILogger<ImportProcessHandler> logger)
        {
            this.processRepo = processRepo;
            this.roleRepo = roleRepo;
            this.defectiveRepo = defectiveRepo;
            this.logger = logger;
        }

        /// <summary>
        /// 导入工序
        /// </summary>
        /// <param name="request">命令</param>
        /// <param name="cancellationToken">取消令牌</param>
        /// <returns>返回统一包装类</returns>
        public async Task<ApiResult<int>> Handle(ImportProcessCommand request, CancellationToken cancellationToken)
        {
            var res = new ApiResult<int>();

            try
            {
                if (request.ProcessList == null || !request.ProcessList.Any())
                {
                    res.Msg = "导入数据为空";
                    res.Code = ApiEnum.Fail;
                    return await System.Threading.Tasks.Task.FromResult(res);
                }

                var successCount = 0;
                var failCount = 0;
                var errorMessages = new List<string>();

                using var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled);
                try
                {
                    foreach (var importItem in request.ProcessList)
                    {
                        try
                        {
                            // 验证必填字段
                            if (string.IsNullOrWhiteSpace(importItem.ProcessName))
                            {
                                errorMessages.Add($"工序名称不能为空");
                                failCount++;
                                continue;
                            }

                            // 验证工序名称唯一性
                            var existingProcess = processRepo.GetAll()
                                .Where(x => !x.IsDeleted && x.ProcessName == importItem.ProcessName)
                                .ToList()
                                .FirstOrDefault();

                            if (existingProcess != null)
                            {
                                errorMessages.Add($"工序名称 '{importItem.ProcessName}' 已存在");
                                failCount++;
                                continue;
                            }

                            // 处理报工权限（将中文角色名称转换为角色ID）
                            var reportingPermissions = await ConvertReportingPermissionsToIds(importItem.ReportingPermissions);

                            // 处理不良品项列表（将中文描述转换为不良品项ID）
                            var defectiveItemList = await ConvertDefectiveItemListToIds(importItem.DefectiveItemList);

                            // 生成雪花ID和工序编号
                            var processId = YitIdHelper.NextId();
                            var processNumber = GenerateProcessNumber();

                            // 创建工序实体
                            var process = new Domain.ZSHH.Process
                            {
                                Id = processId,
                                ProcessNumber = processNumber,
                                ProcessName = importItem.ProcessName,
                                ReportingPermissions = reportingPermissions,
                                ReportingRatio = importItem.ReportingRatio > 0 ? importItem.ReportingRatio : 1,
                                DefectiveItemList = defectiveItemList,
                                TestField1 = importItem.TestField1,
                                TestField2 = importItem.TestField2,
                                Creator = request.Importer,
                                Updator = request.Importer
                            };

                            var result = await processRepo.CreateAsync(process);
                            if (result > 0)
                            {
                                successCount++;
                            }
                            else
                            {
                                failCount++;
                                errorMessages.Add($"工序 '{importItem.ProcessName}' 保存失败");
                            }
                        }
                        catch (Exception ex)
                        {
                            failCount++;
                            errorMessages.Add($"工序 '{importItem.ProcessName}' 处理异常：{ex.Message}");
                            logger.LogError($"导入工序 '{importItem.ProcessName}' 异常：{ex.Message}");
                        }
                    }

                    transaction.Complete();

                    res.Data = successCount;
                    if (successCount > 0)
                    {
                        res.Msg = $"导入完成，成功 {successCount} 条，失败 {failCount} 条";
                        if (errorMessages.Any())
                        {
                            res.Msg += $"，错误信息：{string.Join("; ", errorMessages.Take(5))}";
                        }
                        res.Code = ApiEnum.Success;
                    }
                    else
                    {
                        res.Msg = $"导入失败，共 {failCount} 条记录失败";
                        if (errorMessages.Any())
                        {
                            res.Msg += $"，错误信息：{string.Join("; ", errorMessages.Take(5))}";
                        }
                        res.Code = ApiEnum.Fail;
                    }

                    logger.LogInformation($"导入工序完成，成功 {successCount} 条，失败 {failCount} 条");
                }
                catch (Exception ex)
                {
                    logger.LogError($"导入工序事务异常：{ex.Message}");
                    res.Msg = "导入工序事务异常：" + ex.Message;
                    res.Code = ApiEnum.Error;
                }

                return await System.Threading.Tasks.Task.FromResult(res);
            }
            catch (Exception ex)
            {
                logger.LogError($"导入工序异常：{ex.Message}");
                res.Msg = "导入工序异常：" + ex.Message;
                res.Code = ApiEnum.Error;
                return await System.Threading.Tasks.Task.FromResult(res);
            }
        }

        /// <summary>
        /// 生成工序编号
        /// </summary>
        /// <returns>工序编号</returns>
        private string GenerateProcessNumber()
        {
            var timestamp = DateTime.Now.ToString("yyyyMMddHHmmss");
            var random = new Random();
            var randomPart = random.Next(100000, 999999).ToString();
            return timestamp + randomPart;
        }

        /// <summary>
        /// 将报工权限中文名称转换为角色ID
        /// </summary>
        /// <param name="permissionsText">报工权限文本</param>
        /// <returns>角色ID字符串</returns>
        private async Task<string> ConvertReportingPermissionsToIds(string permissionsText)
        {
            if (string.IsNullOrWhiteSpace(permissionsText))
                return "0"; // 0表示所有人

            if (permissionsText.Contains("所有人") || permissionsText.Contains("所有人"))
                return "0";

            var permissionNames = permissionsText.Split(',', StringSplitOptions.RemoveEmptyEntries)
                .Select(p => p.Trim())
                .Where(p => !string.IsNullOrWhiteSpace(p))
                .ToList();

            if (!permissionNames.Any())
                return "0";

            var roleIds = new List<string>();
            foreach (var permissionName in permissionNames)
            {
                var role = roleRepo.GetAll()
                    .Where(x => !x.IsDeleted && x.RoleName == permissionName)
                    .ToList()
                    .FirstOrDefault();

                if (role != null)
                {
                    roleIds.Add(role.Id.ToString());
                }
                else
                {
                    // 如果找不到角色，记录日志并跳过
                    logger.LogWarning($"导入工序时找不到角色：{permissionName}");
                }
            }

            return roleIds.Any() ? string.Join(",", roleIds) : "0";
        }

        /// <summary>
        /// 将不良品项中文描述转换为不良品项ID
        /// </summary>
        /// <param name="defectiveText">不良品项文本</param>
        /// <returns>不良品项ID字符串</returns>
        private async Task<string> ConvertDefectiveItemListToIds(string defectiveText)
        {
            if (string.IsNullOrWhiteSpace(defectiveText))
                return string.Empty;

            // 解析格式：数量 不良品项编号 | 描述
            var defectiveItems = defectiveText.Split(',', StringSplitOptions.RemoveEmptyEntries)
                .Select(item => item.Trim())
                .Where(item => !string.IsNullOrWhiteSpace(item))
                .ToList();

            if (!defectiveItems.Any())
                return string.Empty;

            var resultItems = new List<string>();
            foreach (var item in defectiveItems)
            {
                // 解析格式：数量 编号 | 描述
                var parts = item.Split('|', StringSplitOptions.RemoveEmptyEntries);
                if (parts.Length >= 2)
                {
                    var quantityAndCode = parts[0].Trim();
                    var description = parts[1].Trim();

                    // 分离数量和编号
                    var quantity = 1;
                    var code = quantityAndCode;
                    
                    // 检查是否以数字开头
                    var firstSpaceIndex = quantityAndCode.IndexOf(' ');
                    if (firstSpaceIndex > 0 && int.TryParse(quantityAndCode.Substring(0, firstSpaceIndex), out var qty))
                    {
                        quantity = qty;
                        code = quantityAndCode.Substring(firstSpaceIndex + 1).Trim();
                    }

                    // 根据描述查找不良品项
                    var defective = defectiveRepo.GetAll()
                        .Where(x => !x.IsDeleted && 
                                  (x.DefectiveName.Contains(description) || 
                                   x.DefectiveCode.Contains(code)))
                        .ToList()
                        .FirstOrDefault();

                    if (defective != null)
                    {
                        resultItems.Add($"{quantity} {defective.DefectiveCode} | {defective.DefectiveName}");
                    }
                    else
                    {
                        // 如果找不到，保留原始格式
                        resultItems.Add(item);
                        logger.LogWarning($"导入工序时找不到不良品项：{description}");
                    }
                }
                else
                {
                    // 如果格式不正确，保留原始内容
                    resultItems.Add(item);
                }
            }

            return string.Join(",", resultItems);
        }
    }
} 